<template>
  <div class="SvgEditor">
    <div id="svgcontainer"></div>
    <div class="editor">
      <iframe
        :src="srcHtml"
        ref="iframe"
        width="100%"
        height="95%"
        scrolling="no"
        class="iframeSvg"
      ></iframe>
      <div style="float: left">
        <el-button @click="vueSendMsg">向内部传递信息</el-button>
        <el-button @click="iframeMethods">触发内部方法</el-button>
      </div>
    </div>
  </div>
</template>

<script>
import * as d3 from "d3";
export default {
  name: "SvgEditor",
  data() {
    return {
      SvgDom: "",
      objSvgDom: {},
      srcHtml: "../SvgEditor/svg.html",
      iframeWin: {},
    };
  },
  mounted() {
    window.addEventListener("message", this.getiframeMsg);
    this.draw();
  },
  methods: {
    draw() {
      d3.xml("../svg/yahei.svg").then(async (data) => {
        let svgdata = data.documentElement;
        document.getElementById("svgcontainer").appendChild(svgdata);

        // 1.将 defs 中的元素存储
        let defs = d3.select("#svgcontainer defs")._groups[0][0];
        await this.recursionDefs(defs);

        // 2.将 defs 中的 use 替换
        await this.loopUseDefs(defs.childNodes);

        // 3-1.获取最新的 DOM 对象
        const defsObj1 = await this.recursionDefs(defs);

        // 3-2.循环 svg 文件，替换所有 use
        const useAll = d3.selectAll("use");
        useAll.each((d, i) => {
          let item = useAll.nodes()[i];
          if (!item.attributes["transform"]) return false;

          // const x = item.attributes["x"].value;
          // const y = item.attributes["y"].value;
          const link = item.attributes["xlink:href"].value.substring(1);
          // const width = item.attributes["width"].value;
          // const height = item.attributes["height"].value;
          // const classAttr = item.attributes["class"].value;

          // 处理位置
          let transform = item.attributes["transform"].value;
          let transformList = transform.split(" ");
          transformList[transformList.length - 1] = "translate(0,0)";
          // transformList = transformList.join(" ");

          let creatSvgDom = defsObj1[link];
          let p = d3.select(item.parentNode);

          item.remove();

          p.append("g")
            .attr("transform", transformList[0])
            .append("g")
            .attr("transform", transformList[1])
            .append("g")
            .attr("transform", transformList[2])
            .append("g")
            .attr("transform", transformList[3])
            .html(creatSvgDom);
        });
        d3.select("defs").remove();

        // 4.把各分组合到一起
        let groupIdList = [
          "Substation_Layer",
          "ConnLine_Layer",
          "ACLineSegment_Layer",
          "BusbarSection_Layer",
          "Junction_Layer",
          "Breaker_Layer",
          "CompositeSwitch_Layer",
          "PowerTransformer_Layer",
          "EnergyConsumer_Layer",
          "Text_Layer",
          "Other_Layer",
          "Disconnector_Layer",
          "PoleCode_Layer",
          "Fuse_Layer",
        ];

        let domList = ``;
        let svgDom1;
        groupIdList.forEach((item) => {
          let BackGround = d3.select(`#${item}`).nodes();
          if (BackGround.length > 0) {
            domList += BackGround[0].innerHTML;
            svgDom1 = BackGround[0].parentNode;
          }
        });

        d3.select(svgDom1).html(domList);

        // 5.添加详细信息
        const metadata = d3.selectAll("metadata").nodes();
        metadata.forEach((item) => {
          let metadataLists = item.childNodes;
          let lists = {};
          metadataLists.forEach((element) => {
            if (element.nodeName == "#text") return;
            if (!lists[element.nodeName]) {
              lists[element.nodeName] = [element.attributes];
            } else {
              lists[element.nodeName].push(element.attributes);
            }
          });

          let p = d3.select(item.parentNode);

          p.attr("VLayerName", lists["cge:layer_ref"][0].objectname.nodeValue);

          p.attr("VID", lists["cge:psr_ref"][0].objectid.nodeValue);

          if (lists["cge:psr_ref"][0].objectname) {
            p.attr("VName", lists["cge:psr_ref"][0].objectname.nodeValue);
          }

          if (lists["cge:glink_ref"]) {
            let glinks = [];
            lists["cge:glink_ref"].forEach((ele) => {
              glinks.push(ele[0].nodeValue);
            });
            p.attr("VLinks", glinks);
          }
        });

        d3.selectAll("metadata").remove();
        let svgRootDom1 = document.getElementById("svgcontainer");
        this.SvgDom = svgRootDom1.innerHTML;

        // setTimeout(() => {
        //   this.vueSendMsg();
        // }, 2000);

        // 6.生成解析过后的svg文件，给工具使用
      });
    },
    /**
     * 解析 defs
     * @param {*} defs
     */
    recursionDefs(defs) {
      if (defs.nodeName == "defs") {
        let symbel = defs.childNodes;
        for (let i = 0; i < symbel.length; i++) {
          if (symbel[i].nodeName != "#text" && symbel[i].nodeName != "style") {
            let id = symbel[i].attributes["id"].value;
            this.objSvgDom[id] = symbel[i].innerHTML;
          }
        }
      }
      return this.objSvgDom;
    },
    /**
     * 解析 defs
     * @param {*} defs
     */
    loopUseDefs(defs) {
      let symbel = defs;
      if (symbel) {
        for (let i = 0; i < symbel.length; i++) {
          let children = symbel[i].childNodes;
          if (symbel[i].nodeName != "#text" && symbel[i].nodeName != "style") {
            if (symbel[i].nodeName == "use") {
              const x = symbel[i].attributes["x"].value;
              const y = symbel[i].attributes["y"].value;
              const link =
                symbel[i].attributes["xlink:href"].value.substring(1);
              let creatSvgDom = this.objSvgDom[link];
              let p = d3.select(symbel[i].parentNode);
              symbel[i].remove();
              const dom = p.append("g").html(creatSvgDom).attr("class", "use");
              dom.select(".use circle").attr("cx", x).attr("cy", y);
            }
            this.loopUseDefs(children);
          }
        }
      }
    },
    // vue获取iframe传递过来的信息
    getiframeMsg(event) {
      const res = event.data;
      console.log(event);
      if (res.cmd == "myIframe") {
        console.log(res);
      }
    },
    // vue向iframe传递信息
    vueSendMsg() {
      const iframeWindow = this.$refs.iframe.contentWindow;
      iframeWindow.postMessage(
        {
          cmd: "myVue",
          params: {
            info: "Vue向iframe传递的消息",
            svg: this.SvgDom,
          },
        },
        "*"
      );
    },
    // 触发iframe中的方法
    iframeMethods() {
      this.$refs.iframe.contentWindow.triggerByVue("通过Vue触发iframe中的方法");
    },
  },
};
</script>

<style scoped>
.iframeSvg {
  border: 0;
}
.SvgEditor {
  width: 100%;
  height: 100%;
  position: relative;
  overflow: hidden;
}

.SvgEditor #svgcontainer {
  display: none;
  position: absolute;
  top: 0;
  left: 0;
}
.SvgEditor .editor {
  /* display: none; */
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
}
</style>
